/* -----------------------------------------------------------------------------
*  CVectorString
*  Author: Antonio Javier Gallego Sánchez (ajgallego AT gmail DOT com)
*  License: GNU Public License
* ----------------------------------------------------------------------------*/

#include "CVectorString.hpp"

#include <iostream>
#include <vector>
#include <algorithm>
#include <string.h>
#include "asrtbas.h"
using namespace std;

struct prv_vectorString_t
{
    vector<const char*> list;
};

//------------------------------------------------------------------------------
//
static struct prv_vectorString_t* prv_create()
{
    prv_vectorString_t *data = new prv_vectorString_t;
    assert_no_null( data );

    return data;
}

//------------------------------------------------------------------------------
//
CVectorString :: CVectorString()
{
    m_data = prv_create();
}

//------------------------------------------------------------------------------
//
CVectorString :: CVectorString( unsigned int size )
{
    m_data = prv_create();

    m_data->list.reserve( size );
}

//------------------------------------------------------------------------------
//
CVectorString :: CVectorString( unsigned int size, const char *str )
{
    m_data = prv_create();

    m_data->list.reserve( size );

    vector<const char*>::iterator it = m_data->list.begin();

    m_data->list.insert ( it, size, str );
}

//------------------------------------------------------------------------------
//
CVectorString :: ~CVectorString()
{
    m_data->list.clear();

    delete m_data;
}

//------------------------------------------------------------------------------
//
unsigned long CVectorString :: size() const
{
    return m_data->list.size();
}

//------------------------------------------------------------------------------
//
bool CVectorString :: empty() const
{
    return m_data->list.empty();
}

//------------------------------------------------------------------------------
//
bool CVectorString :: equal( const CVectorString *vector ) const
{
    if( this->size() != vector->size() )
        return false;

    std::vector<const char*>::const_iterator it1 = m_data->list.begin();
    std::vector<const char*>::const_iterator it2 = vector->m_data->list.begin();

    for ( ; it1 != m_data->list.end(); ++it1, ++it2 )
    {
        if( strcmp( *it1, *it2 ) != 0 )
            return false;
    }

    return true;
}

//------------------------------------------------------------------------------
//
bool CVectorString :: isInVector( const char* str ) const
{
    for( vector<const char*>::const_iterator it = m_data->list.begin();
         it != m_data->list.end(); ++it )
    {
        if( strcmp( *it, str ) == 0 )
            return true;
    }
    return false;
}

//------------------------------------------------------------------------------
//
void CVectorString :: print( char separator ) const
{
    for ( vector<const char*>::const_iterator it = m_data->list.begin();
          it != m_data->list.end(); ++it )
    {
        if( it != m_data->list.begin() )
            cout << separator;

        cout << *it;
    }
}

//------------------------------------------------------------------------------
//
void CVectorString :: resize( unsigned long newsize )
{
    if( newsize < this->size() )
        m_data->list.resize( newsize );
    else
        m_data->list.reserve( newsize );
}

//------------------------------------------------------------------------------
//
const char* CVectorString :: get( unsigned long id ) const
{
    assert( id < this->size() );

    return m_data->list[ id ];
}

//------------------------------------------------------------------------------
//
const char* CVectorString :: front() const
{
    return m_data->list.front();
}

//------------------------------------------------------------------------------
//
const char* CVectorString :: back() const
{
    return m_data->list.back();
}

//------------------------------------------------------------------------------
//
void CVectorString :: push_back( const char* str )
{
    return m_data->list.push_back( str );
}

//------------------------------------------------------------------------------
//
void CVectorString :: pop_back()
{
    return m_data->list.pop_back();
}

//------------------------------------------------------------------------------
//
void CVectorString :: append( const CVectorString *vector )
{
    assert_no_null( vector );

    m_data->list.insert( m_data->list.end(), 
                         vector->m_data->list.begin(),
                         vector->m_data->list.end() );
}

//------------------------------------------------------------------------------
//
void CVectorString :: appendWithoutDuplicates( const CVectorString *vector )
{
    unsigned long size1 = this->size();
    unsigned long size2 = vector->size();

    for( unsigned long id2 = 0; id2 < size2; ++id2 )
    {
        bool notfound = true;

        for( unsigned long id1 = 0; id1 < size1; ++id1 )
        {
            if ( strcmp( this->get( id1 ), vector->get( id2 ) ) == 0 )
            {
                notfound = false;
                break;
            }
        }

        if ( notfound )
        {
            this->push_back( strdup( vector->get( id2 ) ) );
        }
    }
}

/**
*/